/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __PQ_FileSystem_H__
#define __PQ_FileSystem_H__

#include "EnginePrerequisites.h"

namespace PQEngine
{
	class SerializeDatagram;
	/*Represent native filesystem
	*/
	class FileSystem
	{
	protected:
		FileSystem();
	public:
		static const std::string EXT_MATERIAL;
		static const std::string EXT_MESH;
		static const std::string EXT_SKELETON;
		static const std::string EXT_TGA;

		static FileSystem& getSingleton();
		
		static bool isDirExist(std::string path);
		static bool isFileExist(std::string path);

		
		inline static std::string getParentPath(std::string filePath)
		{
			int pos=filePath.find_last_of("/");
			if(pos==std::string::npos){
				return "";//do nothing
			}
			std::string parent=filePath.substr(0,pos);
			return parent;
		}

		inline static std::string getPathLastNode(std::string filePath)
		{
			int pos=filePath.find_last_of("/");
			if(pos==std::string::npos){
				return "";//do nothing
			}
			std::string name=filePath.substr(pos+1);
			return name;
		}

		inline static std::string getPathFirstNode(std::string filePath)
		{
			int pos=filePath.find_first_of("/");
			if(pos==std::string::npos){
				return "";//do nothing
			}
			std::string name=filePath.substr(0,pos);
			return name;
		}

		/*Return path that removed first node
		*/
		inline static std::string removeFirstNode(std::string filePath)
		{
			int pos=filePath.find_first_of("/");
			if(pos==std::string::npos){
				return "";//do nothing
			}
			std::string name=filePath.substr(pos+1);
			return name;
		}

		/*Return path that removed first node
		*/
		inline static std::string removeFileExtension(std::string fileName)
		{
			int pos=fileName.find_last_of(".");
			if(pos==std::string::npos){
				return "";//do nothing
			}
			std::string name=fileName.substr(0,pos);
			return name;
		}

		/*Return file extension string.
		*/
		inline static std::string getFileExtName(std::string fileName)
		{
			int pos=fileName.find_last_of(".");
			if(pos==std::string::npos){
				return "";//do nothing
			}
			std::string ext=fileName.substr(pos+1);
			return ext;
		}

		/*Return file type by file name string.
		*/
		inline static GFileType getFileTypeByName(std::string fileName)
		{
			int pos=fileName.find_last_of(".");
			if(pos==std::string::npos){
				return GFILE_TYPE_UNKOWN;
			}
			std::string ext=fileName.substr(pos+1);
			if(ext=="MESH"||ext=="mesh"||ext=="Mesh"){
				return GFILE_TYPE_MESH;
			}
			if(ext=="MATERIAL"||ext=="material"||ext=="Material"){
				return GFILE_TYPE_MATERIAL;
			}
			if(ext=="SKELETON"||ext=="skeleton"||ext=="Skeleton"){
				return GFILE_TYPE_SKELETON;
			}

			if(ext=="PNG"||ext=="png"||ext=="Png"){
				return GFILE_TYPE_IMAGE_PNG;
			}
			if(ext=="TGA"||ext=="tga"||ext=="Tga"){
				return GFILE_TYPE_IMAGE_TGA;
			}
			if(ext=="DDS"||ext=="dds"||ext=="Dds"){
				return GFILE_TYPE_IMAGE_DDS;
			}

			if(ext=="BLEND"||ext=="blend"||ext=="Blend"){
				return GFILE_TYPE_BLEND;
			}
			
			return GFILE_TYPE_UNKOWN;
		}


		/*Change file path's extension
		*/
		inline static std::string changeExt(std::string fileName,std::string ext)
		{
			int pos=fileName.find_last_of(".");
			if(pos==std::string::npos){
				return fileName;
			}
			std::string path=fileName.substr(0,pos);
			path+=".";
			path+=ext;
			return path;
		}

		/*Create a file if not exist,else just return false.
		*/
		static bool createFile(std::string path);

		/*Create a directory if not exist,else just return false.
		*/
		static bool createDirectory(std::string path);

		static SerializeDatagram* readGData(std::string fileName);
		static void writeGData(std::string fileName,SerializeDatagram* dgram);

	private:
		std::string _currentPath;
	};
}
#define GFileBaseSystem PQEngine::FileSystem::getSingleton()

#endif
